package com.lw.leetcode.binary.b;

/**
 * Created with IntelliJ IDEA.
 * 1712. 将数组分成三个子数组的方案数
 *
 * @author liw
 * @version 1.0
 * @date 2022/2/26 16:05
 */
public class WaysToSplit {


    public static void main(String[] args) {
        WaysToSplit test = new WaysToSplit();

        // 3
//        int[] arr = {1,2,2,2,5,0};

        // 3
//        int[] arr = {3, 2, 1};

        // 1
        int[] arr = {0, 3, 3};

        // 3
//        int[] arr = {0,0,0,0};

        int i = test.waysToSplit(arr);
        System.out.println(i);
    }

    public int waysToSplit(int[] nums) {
        int length = nums.length;
        for (int i = 1; i < length; i++) {
            nums[i] += nums[i - 1];
        }
        long count = 0L;
        int sum = nums[length - 1];
        int l = ((sum / 3) << 1) + 1;
        for (int i = 0; i < length; i++) {
            int a = nums[i] << 1;
            int b = Math.min(((sum + nums[i]) >> 1) + 1, l);
            if (a > b) {
                continue;
            }
            int m = binary2(nums, b);
            int n = binary3(nums, a - 1);
            n = n == 0 ? i + 1 : n;
            m = m == length - 1 ? m - 1 : m;
            if (n == -1 || m == -1 || n > m) {
                continue;
            }
            count = (count + m - n + 1) % 1000000007;
        }
        return (int) count;
    }

    public int binary2(int[] nums, int target) {
        if (nums[0] >= target) {
            return -1;
        }
        int st = 0;
        int end = nums.length - 1;
        while (st < end) {
            int m = st + ((end - st + 1) >> 1);
            if (nums[m] < target) {
                st = m;
            } else {
                end = m - 1;
            }
        }
        return st;
    }

    private int binary3(int[] nums, int target) {
        int end = nums.length - 1;
        if (nums[end] <= target) {
            return -1;
        }
        int st = 0;
        while (st < end) {
            int m = st + ((end - st) >> 1);
            if (nums[m] > target) {
                end = m;
            } else {
                st = m + 1;
            }
        }
        return st;
    }


}
